#include "serialwidget.h"
#include <QMessageBox>
#include <QDateTime>
#include <QDebug>
#include <QEvent>
#include <QMouseEvent>
#include <QTimer>

SerialWidget::SerialWidget(QWidget *parent)
    : QWidget(parent)
    , m_serialManager(nullptr)
    , m_keyboard(nullptr)
    , m_portComboBox(nullptr)
    , m_baudRateComboBox(nullptr)
    , m_dataBitsComboBox(nullptr)
    , m_stopBitsComboBox(nullptr)
    , m_parityComboBox(nullptr)
    , m_refreshButton(nullptr)
    , m_openButton(nullptr)
    , m_closeButton(nullptr)
    , m_statusLabel(nullptr)
    , m_errorLabel(nullptr)
    , m_receiveTextEdit(nullptr)
    , m_hexDisplayCheckBox(nullptr)
    , m_autoWrapCheckBox(nullptr)
    , m_showTimeCheckBox(nullptr)
    , m_clearReceiveButton(nullptr)
    , m_sendTextEdit(nullptr)
    , m_hexSendCheckBox(nullptr)
    , m_addNewlineCheckBox(nullptr)
    , m_autoSendCheckBox(nullptr)
    , m_enableKeyboardCheckBox(nullptr)
    , m_autoSendIntervalSpinBox(nullptr)
    , m_sendButton(nullptr)
    , m_clearSendButton(nullptr)
    , m_rxCountLabel(nullptr)
    , m_txCountLabel(nullptr)
    , m_clearStatsButton(nullptr)
{
    // 创建业务层对象
    m_serialManager = new SerialManager(this);
    
    // 创建虚拟键盘
    m_keyboard = new SimpleKeyboard(this);
    m_keyboard->hide();  // 初始隐藏
    
    setupUI();
    connectSignals();
    scanSerialPorts();
}

SerialWidget::~SerialWidget()
{
}

/**
 * @brief 清理资源（返回主页时调用）
 */
void SerialWidget::cleanup()
{
    // 关闭串口
    if (m_serialManager && m_serialManager->isOpen()) {
        m_serialManager->closePort();
        qDebug() << "串口助手：已关闭串口连接";
    }
    
    // 隐藏虚拟键盘
    if (m_keyboard && m_keyboard->isVisible()) {
        m_keyboard->hide();
    }
    
    qDebug() << "串口助手：资源清理完成";
}

bool SerialWidget::eventFilter(QObject *obj, QEvent *event)
{
    // 不需要事件过滤器了，通过复选框直接控制
    return QWidget::eventFilter(obj, event);
}

void SerialWidget::setupUI()
{
    // 主布局 - 针对1024x600分辨率优化
    QVBoxLayout *mainLayout = new QVBoxLayout(this);
    mainLayout->setContentsMargins(15, 15, 15, 10);
    mainLayout->setSpacing(8);
    
    // ==================== 串口配置区 ====================
    QGroupBox *configGroup = new QGroupBox("串口配置", this);
    configGroup->setMaximumHeight(120);
    QGridLayout *configLayout = new QGridLayout(configGroup);
    configLayout->setSpacing(8);
    configLayout->setContentsMargins(10, 15, 10, 10);
    
    // 第一行：串口号、刷新、波特率
    QLabel *portLabel = new QLabel("串口:", this);
    portLabel->setFixedWidth(45);
    configLayout->addWidget(portLabel, 0, 0);
    
    m_portComboBox = new QComboBox(this);
    m_portComboBox->setMinimumWidth(180);
    m_portComboBox->setMaximumWidth(220);
    configLayout->addWidget(m_portComboBox, 0, 1);
    
    m_refreshButton = new QPushButton("刷新", this);
    m_refreshButton->setFixedSize(60, 28);
    configLayout->addWidget(m_refreshButton, 0, 2);
    
    QLabel *baudLabel = new QLabel("波特率:", this);
    baudLabel->setFixedWidth(55);
    configLayout->addWidget(baudLabel, 0, 3);
    
    m_baudRateComboBox = new QComboBox(this);
    m_baudRateComboBox->addItems({"9600", "19200", "38400", "57600", "115200", "230400", "460800", "921600"});
    m_baudRateComboBox->setCurrentText("115200");
    m_baudRateComboBox->setFixedWidth(100);
    configLayout->addWidget(m_baudRateComboBox, 0, 4);
    
    QLabel *dataLabel = new QLabel("数据位:", this);
    dataLabel->setFixedWidth(55);
    configLayout->addWidget(dataLabel, 0, 5);
    
    m_dataBitsComboBox = new QComboBox(this);
    m_dataBitsComboBox->addItems({"5", "6", "7", "8"});
    m_dataBitsComboBox->setCurrentText("8");
    m_dataBitsComboBox->setFixedWidth(70);
    configLayout->addWidget(m_dataBitsComboBox, 0, 6);
    
    configLayout->setColumnStretch(7, 1); // 最后一列拉伸
    
    // 第二行：停止位、校验位、打开/关闭按钮、状态
    QLabel *stopLabel = new QLabel("停止位:", this);
    stopLabel->setFixedWidth(55);
    configLayout->addWidget(stopLabel, 1, 0);
    
    m_stopBitsComboBox = new QComboBox(this);
    m_stopBitsComboBox->addItem("1", QSerialPort::OneStop);
    m_stopBitsComboBox->addItem("1.5", QSerialPort::OneAndHalfStop);
    m_stopBitsComboBox->addItem("2", QSerialPort::TwoStop);
    m_stopBitsComboBox->setFixedWidth(70);
    configLayout->addWidget(m_stopBitsComboBox, 1, 1);
    
    QLabel *parityLabel = new QLabel("校验位:", this);
    parityLabel->setFixedWidth(55);
    configLayout->addWidget(parityLabel, 1, 2);
    
    m_parityComboBox = new QComboBox(this);
    m_parityComboBox->addItem("None", QSerialPort::NoParity);
    m_parityComboBox->addItem("Even", QSerialPort::EvenParity);
    m_parityComboBox->addItem("Odd", QSerialPort::OddParity);
    m_parityComboBox->addItem("Space", QSerialPort::SpaceParity);
    m_parityComboBox->addItem("Mark", QSerialPort::MarkParity);
    m_parityComboBox->setFixedWidth(90);
    configLayout->addWidget(m_parityComboBox, 1, 3);
    
    m_openButton = new QPushButton("打开串口", this);
    m_openButton->setFixedSize(100, 32);
    m_openButton->setStyleSheet("QPushButton { background-color: #27ae60; color: white; font-weight: bold; }");
    configLayout->addWidget(m_openButton, 1, 4);
    
    m_closeButton = new QPushButton("关闭串口", this);
    m_closeButton->setEnabled(false);
    m_closeButton->setFixedSize(100, 32);
    m_closeButton->setStyleSheet("QPushButton { background-color: #e74c3c; color: white; font-weight: bold; }");
    configLayout->addWidget(m_closeButton, 1, 5);
    
    QLabel *statusTextLabel = new QLabel("状态:", this);
    statusTextLabel->setFixedWidth(45);
    configLayout->addWidget(statusTextLabel, 1, 6);
    
    m_statusLabel = new QLabel("○ 未连接", this);
    m_statusLabel->setStyleSheet("QLabel { color: #95a5a6; font-weight: bold; font-size: 13px; }");
    configLayout->addWidget(m_statusLabel, 1, 7);
    
    mainLayout->addWidget(configGroup);
    
    // ==================== 错误提示区 ====================
    m_errorLabel = new QLabel(this);
    m_errorLabel->setStyleSheet("QLabel { background-color: #e74c3c; color: white; padding: 5px; border-radius: 3px; }");
    m_errorLabel->setWordWrap(true);
    m_errorLabel->setVisible(false);  // 默认隐藏
    mainLayout->addWidget(m_errorLabel);
    
    // ==================== 接收区 ====================
    QHBoxLayout *receiveHeaderLayout = new QHBoxLayout();
    receiveHeaderLayout->setSpacing(5);
    QLabel *receiveLabel = new QLabel("接收区", this);
    receiveLabel->setStyleSheet("font-weight: bold; font-size: 13px;");
    receiveHeaderLayout->addWidget(receiveLabel);
    receiveHeaderLayout->addStretch();
    
    m_clearReceiveButton = new QPushButton("清空", this);
    m_clearReceiveButton->setFixedSize(70, 26);
    receiveHeaderLayout->addWidget(m_clearReceiveButton);
    mainLayout->addLayout(receiveHeaderLayout);
    
    m_receiveTextEdit = new QTextEdit(this);
    m_receiveTextEdit->setReadOnly(true);
    m_receiveTextEdit->setFixedHeight(160);
    m_receiveTextEdit->setStyleSheet("QTextEdit { font-size: 11px; line-height: 1.3; }");
    mainLayout->addWidget(m_receiveTextEdit);
    
    // 接收选项
    QHBoxLayout *receiveOptionsLayout = new QHBoxLayout();
    receiveOptionsLayout->setSpacing(15);
    m_hexDisplayCheckBox = new QCheckBox("十六进制显示", this);
    m_autoWrapCheckBox = new QCheckBox("自动换行", this);
    m_autoWrapCheckBox->setChecked(true);
    m_showTimeCheckBox = new QCheckBox("显示时间戳", this);
    m_showTimeCheckBox->setChecked(true);
    receiveOptionsLayout->addWidget(m_hexDisplayCheckBox);
    receiveOptionsLayout->addWidget(m_autoWrapCheckBox);
    receiveOptionsLayout->addWidget(m_showTimeCheckBox);
    receiveOptionsLayout->addStretch();
    mainLayout->addLayout(receiveOptionsLayout);
    
    // ==================== 发送区 ====================
    QHBoxLayout *sendHeaderLayout = new QHBoxLayout();
    sendHeaderLayout->setSpacing(5);
    QLabel *sendLabel = new QLabel("发送区", this);
    sendLabel->setStyleSheet("font-weight: bold; font-size: 13px;");
    sendHeaderLayout->addWidget(sendLabel);
    sendHeaderLayout->addStretch();
    
    m_clearSendButton = new QPushButton("清空", this);
    m_clearSendButton->setFixedSize(70, 26);
    sendHeaderLayout->addWidget(m_clearSendButton);
    mainLayout->addLayout(sendHeaderLayout);
    
    m_sendTextEdit = new QTextEdit(this);
    m_sendTextEdit->setFixedHeight(70);
    m_sendTextEdit->setPlaceholderText("勾选虚拟键盘后输入...");
    m_sendTextEdit->setStyleSheet("QTextEdit { font-size: 11px; }");
    mainLayout->addWidget(m_sendTextEdit);
    
    // 发送选项和按钮在同一行
    QHBoxLayout *sendControlLayout = new QHBoxLayout();
    sendControlLayout->setSpacing(15);
    
    m_hexSendCheckBox = new QCheckBox("十六进制", this);
    m_addNewlineCheckBox = new QCheckBox("添加换行", this);
    m_autoSendCheckBox = new QCheckBox("循环发送", this);
    
    // ✨ 虚拟键盘开关
    m_enableKeyboardCheckBox = new QCheckBox("虚拟键盘", this);
    m_enableKeyboardCheckBox->setStyleSheet("QCheckBox { color: #e67e22; font-weight: bold; }");
    
    m_autoSendIntervalSpinBox = new QSpinBox(this);
    m_autoSendIntervalSpinBox->setRange(100, 10000);
    m_autoSendIntervalSpinBox->setValue(1000);
    m_autoSendIntervalSpinBox->setSuffix(" ms");
    m_autoSendIntervalSpinBox->setFixedWidth(95);
    
    m_sendButton = new QPushButton("发送", this);
    m_sendButton->setEnabled(false);
    m_sendButton->setFixedSize(80, 32);
    m_sendButton->setStyleSheet("QPushButton { background-color: #3498db; color: white; font-weight: bold; }");
    
    sendControlLayout->addWidget(m_hexSendCheckBox);
    sendControlLayout->addWidget(m_addNewlineCheckBox);
    sendControlLayout->addWidget(m_autoSendCheckBox);
    sendControlLayout->addWidget(m_autoSendIntervalSpinBox);
    sendControlLayout->addWidget(m_enableKeyboardCheckBox);  // 添加虚拟键盘开关
    sendControlLayout->addStretch();
    sendControlLayout->addWidget(m_sendButton);
    
    mainLayout->addLayout(sendControlLayout);
    
    // ==================== 统计信息 ====================
    QHBoxLayout *statsLayout = new QHBoxLayout();
    statsLayout->setSpacing(10);
    
    QLabel *statsTextLabel = new QLabel("统计:", this);
    statsTextLabel->setStyleSheet("font-weight: bold;");
    statsLayout->addWidget(statsTextLabel);
    
    m_rxCountLabel = new QLabel("接收: 0 字节", this);
    m_rxCountLabel->setStyleSheet("color: #27ae60; font-weight: bold;");
    m_txCountLabel = new QLabel("发送: 0 字节", this);
    m_txCountLabel->setStyleSheet("color: #3498db; font-weight: bold;");
    m_clearStatsButton = new QPushButton("清空统计", this);
    m_clearStatsButton->setFixedSize(85, 26);
    
    statsLayout->addWidget(m_rxCountLabel);
    statsLayout->addSpacing(15);
    statsLayout->addWidget(m_txCountLabel);
    statsLayout->addSpacing(15);
    statsLayout->addWidget(m_clearStatsButton);
    statsLayout->addStretch();
    
    mainLayout->addLayout(statsLayout);
}

void SerialWidget::connectSignals()
{
    // UI控件信号
    connect(m_refreshButton, &QPushButton::clicked, this, &SerialWidget::onRefreshPorts);
    connect(m_openButton, &QPushButton::clicked, this, &SerialWidget::onOpenPort);
    connect(m_closeButton, &QPushButton::clicked, this, &SerialWidget::onClosePort);
    connect(m_sendButton, &QPushButton::clicked, this, &SerialWidget::onSendData);
    connect(m_clearReceiveButton, &QPushButton::clicked, this, &SerialWidget::onClearReceive);
    connect(m_clearSendButton, &QPushButton::clicked, this, &SerialWidget::onClearSend);
    connect(m_clearStatsButton, &QPushButton::clicked, this, &SerialWidget::onClearStatistics);
    connect(m_autoSendCheckBox, &QCheckBox::toggled, this, &SerialWidget::onAutoSendToggled);
    
    // 虚拟键盘复选框：勾选=显示键盘，取消勾选=隐藏键盘
    connect(m_enableKeyboardCheckBox, &QCheckBox::toggled, this, [this](bool checked) {
        if (checked) {
            qDebug() << "[SerialWidget] 显示虚拟键盘";
            m_keyboard->setText(m_sendTextEdit->toPlainText());  // 加载当前发送区内容
            m_keyboard->move(112, 350);  // 固定位置
            m_keyboard->show();
            m_keyboard->raise();
            m_keyboard->activateWindow();
        } else {
            qDebug() << "[SerialWidget] 隐藏虚拟键盘";
            m_keyboard->hide();
        }
    });
    
    // 虚拟键盘"完成"按钮：传输内容到发送区 + 隐藏键盘 + 取消勾选
    connect(m_keyboard, &SimpleKeyboard::enterPressed, this, [this]() {
        QString text = m_keyboard->getText();
        qDebug() << "[SerialWidget] 键盘完成输入，内容：" << text;
        m_sendTextEdit->setPlainText(text);  // 传给发送区
        m_keyboard->hide();  // 隐藏键盘
        m_enableKeyboardCheckBox->setChecked(false);  // 取消勾选
    });
    
    // 业务层信号
    connect(m_serialManager, &SerialManager::dataReceived, this, &SerialWidget::onDataReceived);
    connect(m_serialManager, &SerialManager::portOpened, this, &SerialWidget::onPortOpened);
    connect(m_serialManager, &SerialManager::portClosed, this, &SerialWidget::onPortClosed);
    connect(m_serialManager, &SerialManager::errorOccurred, this, &SerialWidget::onError);
    connect(m_serialManager, &SerialManager::statisticsUpdated, this, &SerialWidget::onStatisticsUpdated);
}

void SerialWidget::scanSerialPorts()
{
    m_portComboBox->clear();
    QList<QSerialPortInfo> ports = m_serialManager->getAvailablePorts();
    
    if (ports.isEmpty()) {
        m_portComboBox->addItem("未找到可用串口");
        m_openButton->setEnabled(false);
    } else {
        m_openButton->setEnabled(true);
        for (const QSerialPortInfo &port : ports) {
            m_portComboBox->addItem(port.portName() + " - " + port.description(), port.portName());
        }
    }
}

SerialConfig SerialWidget::getConfigFromUI() const
{
    SerialConfig config;
    
    // 基本配置
    config.portName = m_portComboBox->currentData().toString();
    config.baudRate = SerialConfig::toBaudRate(m_baudRateComboBox->currentText().toInt());
    config.dataBits = static_cast<QSerialPort::DataBits>(m_dataBitsComboBox->currentText().toInt());
    config.stopBits = static_cast<QSerialPort::StopBits>(m_stopBitsComboBox->currentData().toInt());
    config.parity = static_cast<QSerialPort::Parity>(m_parityComboBox->currentData().toInt());
    
    // 显示选项
    config.hexDisplay = m_hexDisplayCheckBox->isChecked();
    config.autoWrap = m_autoWrapCheckBox->isChecked();
    config.showTimestamp = m_showTimeCheckBox->isChecked();
    
    // 发送选项
    config.hexSend = m_hexSendCheckBox->isChecked();
    config.addNewline = m_addNewlineCheckBox->isChecked();
    config.autoSend = m_autoSendCheckBox->isChecked();
    config.autoSendInterval = m_autoSendIntervalSpinBox->value();
    
    return config;
}

void SerialWidget::onRefreshPorts()
{
    scanSerialPorts();
}

void SerialWidget::onOpenPort()
{
    SerialConfig config = getConfigFromUI();
    
    if (config.portName.isEmpty()) {
        QMessageBox::warning(this, "错误", "请选择有效的串口");
        return;
    }
    
    // 调用业务层打开串口
    if (!m_serialManager->openPort(config)) {
        QMessageBox::critical(this, "错误", 
                              QString("无法打开串口: %1\n错误: %2")
                              .arg(config.portName)
                              .arg(m_serialManager->getErrorString()));
    }
}

void SerialWidget::onClosePort()
{
    // 调用业务层关闭串口
    m_serialManager->closePort();
}

void SerialWidget::onSendData()
{
    QString sendText = m_sendTextEdit->toPlainText();
    if (sendText.isEmpty()) {
        return;
    }
    
    qint64 result = -1;
    
    // 根据选项调用不同的发送方法
    if (m_hexSendCheckBox->isChecked()) {
        result = m_serialManager->sendHex(sendText);
        if (result < 0) {
            QMessageBox::warning(this, "警告", "十六进制格式错误\n格式示例: 01 02 03 FF");
        }
    } else {
        result = m_serialManager->sendText(sendText, m_addNewlineCheckBox->isChecked());
    }
    
    if (result < 0) {
        QMessageBox::warning(this, "警告", "发送失败");
    }
}

void SerialWidget::onClearReceive()
{
    m_receiveTextEdit->clear();
}

void SerialWidget::onClearSend()
{
    m_sendTextEdit->clear();
}

void SerialWidget::onClearStatistics()
{
    m_serialManager->clearStatistics();
}

void SerialWidget::onAutoSendToggled(bool checked)
{
    if (checked) {
        if (!m_serialManager->isOpen()) {
            QMessageBox::warning(this, "警告", "请先打开串口");
            m_autoSendCheckBox->setChecked(false);
            return;
        }
        
        QString sendText = m_sendTextEdit->toPlainText();
        if (sendText.isEmpty()) {
            QMessageBox::warning(this, "警告", "发送内容不能为空");
            m_autoSendCheckBox->setChecked(false);
            return;
        }
        
        // 准备发送数据
        QByteArray data;
        if (m_hexSendCheckBox->isChecked()) {
            bool ok;
            data = SerialManager::hexToByteArray(sendText, &ok);
            if (!ok) {
                QMessageBox::warning(this, "警告", "十六进制格式错误");
                m_autoSendCheckBox->setChecked(false);
                return;
            }
        } else {
            data = sendText.toUtf8();
            if (m_addNewlineCheckBox->isChecked()) {
                data.append("\r\n");
            }
        }
        
        // 启动自动发送
        int interval = m_autoSendIntervalSpinBox->value();
        m_serialManager->startAutoSend(data, interval);
    } else {
        // 停止自动发送
        m_serialManager->stopAutoSend();
    }
}

// ==================== 业务层信号响应 ====================

void SerialWidget::onDataReceived(const QByteArray &data)
{
    QString displayText;
    
    // 添加时间戳
    if (m_showTimeCheckBox->isChecked()) {
        QString timestamp = QDateTime::currentDateTime().toString("[yyyy-MM-dd hh:mm:ss] ");
        displayText += timestamp;
    }
    
    // 判断显示格式
    if (m_hexDisplayCheckBox->isChecked()) {
        displayText += "RX: " + SerialManager::byteArrayToHex(data);
    } else {
        displayText += "RX: " + QString::fromUtf8(data);
    }
    
    // 添加到接收区
    m_receiveTextEdit->append(displayText);
    
    // 自动滚动到底部
    if (m_autoWrapCheckBox->isChecked()) {
        m_receiveTextEdit->moveCursor(QTextCursor::End);
    }
}

void SerialWidget::onPortOpened()
{
    updateUIState(true);
    // 清除错误提示
    m_errorLabel->setVisible(false);
}

void SerialWidget::onPortClosed()
{
    updateUIState(false);
    
    // 停止自动发送
    if (m_autoSendCheckBox->isChecked()) {
        m_autoSendCheckBox->setChecked(false);
    }
    
    // 清除错误提示
    m_errorLabel->setVisible(false);
}

void SerialWidget::onError(const QString &error)
{
    // 在顶部错误标签显示（红色醒目提示）
    m_errorLabel->setText(QString("⚠ 串口错误: %1").arg(error));
    m_errorLabel->setVisible(true);
    
    qDebug() << "[SerialWidget] 显示错误:" << error;
}

void SerialWidget::onStatisticsUpdated(quint64 rxCount, quint64 txCount)
{
    m_rxCountLabel->setText(QString("接收: %1 字节").arg(rxCount));
    m_txCountLabel->setText(QString("发送: %1 字节").arg(txCount));
}

void SerialWidget::updateUIState(bool connected)
{
    if (connected) {
        // 已连接状态
        m_statusLabel->setText("● 已连接");
        m_statusLabel->setStyleSheet("QLabel { color: #27ae60; font-weight: bold; }");
        
        m_openButton->setEnabled(false);
        m_closeButton->setEnabled(true);
        m_sendButton->setEnabled(true);
        
        // 禁用配置控件
        m_portComboBox->setEnabled(false);
        m_baudRateComboBox->setEnabled(false);
        m_dataBitsComboBox->setEnabled(false);
        m_stopBitsComboBox->setEnabled(false);
        m_parityComboBox->setEnabled(false);
        m_refreshButton->setEnabled(false);
    } else {
        // 未连接状态
        m_statusLabel->setText("○ 未连接");
        m_statusLabel->setStyleSheet("QLabel { color: #95a5a6; font-weight: bold; }");
        
        m_openButton->setEnabled(true);
        m_closeButton->setEnabled(false);
        m_sendButton->setEnabled(false);
        
        // 启用配置控件
        m_portComboBox->setEnabled(true);
        m_baudRateComboBox->setEnabled(true);
        m_dataBitsComboBox->setEnabled(true);
        m_stopBitsComboBox->setEnabled(true);
        m_parityComboBox->setEnabled(true);
        m_refreshButton->setEnabled(true);
    }
}

